package rolesystem.middle.utilityclasses;

import java.io.Serializable;
import java.util.ArrayList;

import rolesystem.middle.managers.EnvironmentManager;

public class KnownEnvironment implements Serializable
{
	private ArrayList<Square>[][] env_discovered;
	
	public KnownEnvironment()
	{
		
		env_discovered=new ArrayList[EnvironmentManager.ENV_MAX_X][EnvironmentManager.ENV_MAX_Y];
		
	  	// Initialize the Square(s)
	  	for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
	  	{
	  		for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
	  		{
	  			env_discovered[i][j]=new ArrayList<Square>();
	  			env_discovered[i][j].add(new Square());
	  		}    
	  	}  
	}
	
	
	public synchronized void addKnownPosition(PositionSq position,boolean blocked)
	{
		Square knownsquare = env_discovered[position.x][position.y].get(0);
		
		knownsquare.setKnown(true); // setta
		knownsquare.setBlocked(blocked);
		
		env_discovered[position.x][position.y].set(0, knownsquare);
	}
	
	public synchronized ArrayList<Square>[][] getKnownPositions()
	{
		return env_discovered;
	}
	
	public synchronized Square getKnownPosition(PositionSq position)
	{
		return env_discovered[position.x][position.y].get(0);
	}
	
	public synchronized int getBlockedNumber()
	{
	  	int blockedNumber=0;
		
		for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
	  	{
	  		for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
	  		{
	  			if(env_discovered[i][j].get(0).getBlocked()==true)
	  				blockedNumber++;
	  		}    
	  	}  
		
		return blockedNumber;
	}
	
	public synchronized int getKnownNumber()
	{
	  	int knownNumber=0;
		
		for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
	  	{
	  		for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
	  		{
	  			if(env_discovered[i][j].get(0).getKnown()==true)
	  				knownNumber++;
	  		}    
	  	}  
		
		return knownNumber;
	}
	
	public synchronized void merge(KnownEnvironment informationToMerge)
	{
		if(informationToMerge==null)
			return;
		
	  	for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
	  	{
	  		for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
	  		{
	  			PositionSq index_position=new PositionSq(i,j);
	  			Square index_square=informationToMerge.getKnownPosition(index_position); 

	  			if(index_square.getKnown()==true)
	  				addKnownPosition(index_position,index_square.getBlocked());	
	  		}    
	  	}  
	}
	
	public synchronized ArrayList<PositionSq> searchNeighborhood(PositionSq position, int range)
	{
		ArrayList<PositionSq> possible_route= new ArrayList<PositionSq>();
				  
		// Check for possible position choices
		for(int i=-range;i<=range;i++)
		{
			for(int j=-range;j<=range;j++)
			{
				if(i==0 && j==0)
				  continue;
						  
				PositionSq candidate_pos=new PositionSq(position.x+i, position.y+j);
				if(candidate_pos.checkBounds())
				  continue;
						  
				// FIXME necessario blocked in questo caso?		  
				 if(env_discovered[candidate_pos.x][candidate_pos.y].get(0).getBlocked()==false && env_discovered[candidate_pos.x][candidate_pos.y].get(0).getKnown()==false)
				 {  
					 possible_route.add(candidate_pos); 
				 }
			}  
		}  
				  		  
		return possible_route; 
	}
	

	
}
